/**
 * 状态管理器 - 管理排班表的所有数据状态
 * 提供数据的增删改查功能
 */

import type { Employee, Shift, ViewMode, DateRange, ScheduleConfig } from '../types'
import { ScheduleEvents } from '../types'
import { EventBus } from './EventBus'

export class StateManager {
  private employees: Map<string | number, Employee>
  private shifts: Map<string | number, Shift>
  private viewMode: ViewMode
  private dateRange: DateRange
  private config: ScheduleConfig
  private eventBus: EventBus

  constructor(eventBus: EventBus, config: ScheduleConfig = {}) {
    this.employees = new Map()
    this.shifts = new Map()
    this.viewMode = config.defaultView || 'week'
    this.dateRange = this.getDefaultDateRange()
    this.config = config
    this.eventBus = eventBus
  }

  // ==================== 员工管理 ====================

  /**
   * 获取所有员工
   */
  getEmployees(): Employee[] {
    return Array.from(this.employees.values())
  }

  /**
   * 获取指定员工
   */
  getEmployee(id: string | number): Employee | undefined {
    return this.employees.get(id)
  }

  /**
   * 添加员工
   */
  addEmployee(employee: Employee): void {
    this.employees.set(employee.id, employee)
    this.eventBus.emit(ScheduleEvents.EMPLOYEE_ADDED, employee)
  }

  /**
   * 批量添加员工
   */
  addEmployees(employees: Employee[]): void {
    employees.forEach(emp => this.addEmployee(emp))
  }

  /**
   * 更新员工
   */
  updateEmployee(id: string | number, updates: Partial<Employee>): void {
    const employee = this.employees.get(id)
    if (!employee) {
      throw new Error(`Employee with id "${id}" not found`)
    }

    const updatedEmployee = { ...employee, ...updates, id }
    this.employees.set(id, updatedEmployee)
    this.eventBus.emit(ScheduleEvents.EMPLOYEE_UPDATED, updatedEmployee)
  }

  /**
   * 删除员工
   */
  removeEmployee(id: string | number): void {
    const employee = this.employees.get(id)
    if (employee) {
      this.employees.delete(id)
      // 同时删除该员工的所有班次
      const employeeShifts = this.getShiftsByEmployee(id)
      employeeShifts.forEach(shift => this.removeShift(shift.id))
      this.eventBus.emit(ScheduleEvents.EMPLOYEE_REMOVED, employee)
    }
  }

  // ==================== 班次管理 ====================

  /**
   * 获取所有班次
   */
  getShifts(): Shift[] {
    return Array.from(this.shifts.values())
  }

  /**
   * 获取指定班次
   */
  getShift(id: string | number): Shift | undefined {
    return this.shifts.get(id)
  }

  /**
   * 获取指定日期范围的班次
   */
  getShiftsByDateRange(start: string, end: string): Shift[] {
    return this.getShifts().filter(shift => {
      return shift.date >= start && shift.date <= end
    })
  }

  /**
   * 获取指定员工的班次
   */
  getShiftsByEmployee(employeeId: string | number): Shift[] {
    return this.getShifts().filter(shift => shift.employeeId === employeeId)
  }

  /**
   * 获取指定日期的班次
   */
  getShiftsByDate(date: string): Shift[] {
    return this.getShifts().filter(shift => shift.date === date)
  }

  /**
   * 获取指定员工指定日期的班次
   */
  getShiftByEmployeeAndDate(employeeId: string | number, date: string): Shift | undefined {
    return this.getShifts().find(shift => shift.employeeId === employeeId && shift.date === date)
  }

  /**
   * 添加班次
   */
  addShift(shift: Shift): void {
    this.shifts.set(shift.id, shift)
    this.eventBus.emit(ScheduleEvents.SHIFT_ADDED, shift)
  }

  /**
   * 批量添加班次
   */
  addShifts(shifts: Shift[]): void {
    shifts.forEach(shift => this.addShift(shift))
  }

  /**
   * 更新班次
   */
  updateShift(id: string | number, updates: Partial<Shift>): void {
    const shift = this.shifts.get(id)
    if (!shift) {
      throw new Error(`Shift with id "${id}" not found`)
    }

    const updatedShift = { ...shift, ...updates, id }
    this.shifts.set(id, updatedShift)
    this.eventBus.emit(ScheduleEvents.SHIFT_UPDATED, updatedShift)
  }

  /**
   * 删除班次
   */
  removeShift(id: string | number): void {
    const shift = this.shifts.get(id)
    if (shift) {
      this.shifts.delete(id)
      this.eventBus.emit(ScheduleEvents.SHIFT_REMOVED, shift)
    }
  }

  /**
   * 删除指定员工的所有班次
   */
  removeShiftsByEmployee(employeeId: string | number): void {
    const shifts = this.getShiftsByEmployee(employeeId)
    shifts.forEach(shift => this.removeShift(shift.id))
  }

  /**
   * 删除指定日期的所有班次
   */
  removeShiftsByDate(date: string): void {
    const shifts = this.getShiftsByDate(date)
    shifts.forEach(shift => this.removeShift(shift.id))
  }

  // ==================== 视图模式管理 ====================

  /**
   * 获取当前视图模式
   */
  getViewMode(): ViewMode {
    return this.viewMode
  }

  /**
   * 设置视图模式
   */
  setViewMode(mode: ViewMode): void {
    if (this.viewMode !== mode) {
      this.viewMode = mode
      this.eventBus.emit(ScheduleEvents.VIEW_CHANGED, mode)
    }
  }

  // ==================== 日期范围管理 ====================

  /**
   * 获取当前日期范围
   */
  getDateRange(): DateRange {
    return { ...this.dateRange }
  }

  /**
   * 设置日期范围
   */
  setDateRange(range: DateRange): void {
    this.dateRange = range
    this.eventBus.emit(ScheduleEvents.DATE_RANGE_CHANGED, range)
  }

  /**
   * 获取默认日期范围（当前周）
   */
  private getDefaultDateRange(): DateRange {
    const today = new Date()
    const dayOfWeek = today.getDay()
    const startOfWeek = new Date(today)
    startOfWeek.setDate(today.getDate() - (dayOfWeek === 0 ? 6 : dayOfWeek - 1))

    const endOfWeek = new Date(startOfWeek)
    endOfWeek.setDate(startOfWeek.getDate() + 6)

    return {
      start: this.formatDate(startOfWeek),
      end: this.formatDate(endOfWeek),
    }
  }

  /**
   * 格式化日期为 YYYY-MM-DD
   */
  private formatDate(date: Date): string {
    const year = date.getFullYear()
    const month = String(date.getMonth() + 1).padStart(2, '0')
    const day = String(date.getDate()).padStart(2, '0')
    return `${year}-${month}-${day}`
  }

  // ==================== 配置管理 ====================

  /**
   * 获取配置
   */
  getConfig(): ScheduleConfig {
    return { ...this.config }
  }

  /**
   * 更新配置
   */
  updateConfig(updates: Partial<ScheduleConfig>): void {
    this.config = { ...this.config, ...updates }
    this.eventBus.emit(ScheduleEvents.CONFIG_UPDATED, this.config)
  }

  // ==================== 数据统计 ====================

  /**
   * 获取数据统计
   */
  getStatistics() {
    return {
      totalEmployees: this.employees.size,
      totalShifts: this.shifts.size,
      shiftsInRange: this.getShiftsByDateRange(this.dateRange.start, this.dateRange.end).length,
    }
  }

  // ==================== 数据清空 ====================

  /**
   * 清空所有数据
   */
  clear(): void {
    this.employees.clear()
    this.shifts.clear()
  }

  /**
   * 清空班次数据
   */
  clearShifts(): void {
    this.shifts.clear()
  }
}
